package service

import (
	"batbat-backend/app/dao"
	"batbat-backend/app/model"
	"context"
	"github.com/gogf/gf/database/gdb"
	"github.com/gogf/gf/errors/gerror"
	"github.com/gogf/gf/frame/g"
)

var Category = categoryService{}

type categoryService struct{}

// GetAllCategory 获取所有游戏种类
func (c *categoryService) GetAllCategory(ctx context.Context) ([]*model.Category, error) {
	categories := make([]*model.Category, 0)
	err := dao.Category.Fields(dao.Category.Columns).
		InnerJoin("(SELECT cid FROM game_category AS gc "+
			"INNER JOIN ( SELECT id FROM game ORDER BY update_time DESC, `rank` ASC LIMIT 150 ) AS t "+
			"ON t.id = gc.gid "+
			"GROUP BY cid  "+
			"ORDER BY COUNT( 1 ) DESC LIMIT 8)", "tt", "tt.cid=category.id").
		Scan(&categories)
	if err != nil {
		g.Log().Ctx(ctx).Errorf("查询数据库发生错误: %v", err)
		return nil, gerror.New("获取分类列表失败")
	}
	return categories, nil
}

// Games 获取游戏种类下的游戏
func (c *categoryService) Games(ctx context.Context, id uint, pn int, limit int) (
	resp *model.CategoryApiGamesResp, err error) {
	err = g.DB().Transaction(ctx, func(ctx context.Context, tx *gdb.TX) error {
		resp = &model.CategoryApiGamesResp{
			Page: model.Page{
				Prev:  pn - 1,
				Limit: limit,
			},
			List: make([]*model.GameResp, 0),
		}
		// 查找总数
		count, err := dao.GameCategory.Ctx(ctx).TX(tx).Where(dao.GameCategory.Columns.Cid, id).Count()
		if err != nil {
			g.Log().Ctx(ctx).Errorf("查询数据库失败: %v", err)
			return gerror.New("获取游戏列表失败")
		}
		if count == 0 {
			return gerror.New("该分类下没有游戏")
		}
		resp.Count = count
		// 计算下一页
		if pn*limit >= count {
			resp.Next = 0
		} else {
			resp.Next = pn + 1
		}
		// 获取游戏
		var games []*model.Game
		err = dao.Game.Ctx(ctx).TX(tx).
			Fields(dao.Game.Columns).
			WhereIn(dao.Game.Columns.Id,
				dao.GameCategory.Fields(dao.GameCategory.Columns.Gid).Where(dao.GameCategory.Columns.Cid, id)).
			Order(dao.Game.Columns.UpdateTime, "DESC, ", dao.Game.Columns.Rank, "ASC").
			Page(pn, limit).
			Scan(&games)
		if err != nil {
			g.Log().Ctx(ctx).Errorf("查询数据库失败: %v", err)
			return gerror.New("获取游戏列表失败")
		}
		if games == nil || len(games) == 0 {
			return gerror.New("获取游戏列表失败, 请校验参数`pn`或`limit`")
		}
		resp.List = make([]*model.GameResp, len(games))
		for i, game := range games {
			resp.List[i], err = Game.getGameHelper(ctx, game)
			if err != nil {
				g.Log().Ctx(ctx).Errorf("获取游戏信息失败: %v", err)
				return gerror.New("获取游戏列表失败")
			}
		}
		return nil
	})
	return resp, err
}
